package sample.crawler.base;

import com.alibaba.fastjson.JSONObject;
import javafx.concurrent.Task;
import javafx.scene.control.TableView;
import sample.enums.MapType;
import sample.model.Company;
import sample.utils.HttpRequestor;
import sample.utils.LogUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class BaseTask extends Task<Void> {
    public String keywords;
    public List<String> exclusiveWords;
    public String area;
    /** 过滤无效电话*/
    public boolean filterTel;
    public TableView<Company> qrTable;
    protected Integer totalPage = 1;
    protected Integer pageSize = 20;
    static Map<String, Boolean> firstRequest = new HashMap<>();
    protected String mapCode;

    protected String url;
    private Boolean stop;

    protected void initFirstRequest(String type){
        if(firstRequest.get(type) != null) firstRequest.remove(type);
    }

    public void start() {
        new Thread(this).start();
    }

    public void setStop(Boolean stop){
        this.stop = stop;
    }

    public Boolean getStop(){
        return this.stop;
    }

    @Override
    protected Void call() throws Exception {
        for (int pageNo = 1; pageNo <= totalPage; pageNo++) {
            LogUtils.logger.info("[{}] start to request, keywords:{}, area:{}, pageNo:{}", mapCode, keywords, area, pageNo);
            if(isCancelled()) {
                updateMessage(MapType.map.get(mapCode) + "["+keywords+"]：取消");
                break;
            }

            JSONObject jsonObject = request(pageNo);
            LogUtils.logger.info("[{}] succeed to request, keywords:{}, area:{}, pageNo:{}", mapCode, keywords, area, pageNo);


            try {
                fillTable(jsonObject);
            } catch (Exception e) {
                updateMessage(MapType.map.get(mapCode) + "["+keywords+"]异常："+e.getMessage());
                break;
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                break;
            }
        }
        return null;
    }

    public void bindTableView(TableView<Company> qrTable){
        this.qrTable = qrTable;
    }

    public void setQueryCondition(String keywords, List<String> exclusiveWords, String area, Boolean filterTel) {

        this.keywords = keywords;
        this.exclusiveWords = exclusiveWords;
        this.filterTel = filterTel;

        // 除高德以外，其他只支持到市的查询
        String[] areas = area.split(",");
        String city = areas[1];
        String district = areas[2];
        this.area = mapCode.equals(MapType.gaode.getCode()) ? district : city.replaceAll("市","");
    }

    public abstract String getUrl(Integer pageNo);
    public abstract Integer getTotalCount(JSONObject res);
    public abstract void fillTable(JSONObject res) throws Exception;


    protected JSONObject request(Integer pageNo){

        String url = getUrl(pageNo);
        String json = null;
        try {

            json = (MapType.sogou.getCode().equals(mapCode)) ? new HttpRequestor().doGet(url, "application/json", true) : new HttpRequestor().doGet(url);
            LogUtils.logger.info("[{}] succeed send request:{}", mapCode, url);
        } catch (Exception e) {
            LogUtils.logger.error("[{}] send request call exception, url:{}, e:{}", mapCode, url, e);
            e.printStackTrace();
        }


        JSONObject jsonObject = JSONObject.parseObject(json);

        if(firstRequest.get(mapCode) == null || firstRequest.get(mapCode)) {

            Integer total = getTotalCount(jsonObject);
            LogUtils.logger.info("[{}] first request, totalCount:{}", mapCode, total);
            if(total == null) {
                totalPage = 0;
            } else {
                totalPage = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
            }
            LogUtils.logger.info("[{}] first request, keywords:{}, area:{}, totalPage:{}", mapCode, keywords, area, totalPage);
            firstRequest.put(mapCode, false);
        }
        return jsonObject;
    }

    @Override
    protected void scheduled() {
        super.scheduled();
        updateMessage("Scheduled");
    }

    @Override
    protected void running() {
        super.running();
        updateMessage(MapType.map.get(mapCode)+"["+keywords+"]：执行中");
    }

    @Override
    protected void succeeded() {
        super.succeeded();
        initFirstRequest(mapCode);
        updateMessage(MapType.map.get(mapCode)+ "["+keywords+"]：完成");
    }

    @Override
    protected void cancelled() {
        super.cancelled();
        initFirstRequest(mapCode);
        updateMessage(MapType.map.get(mapCode) + "["+keywords+"]：取消");
    }

    @Override
    protected void failed() {
        super.failed();
        initFirstRequest(mapCode);
        updateMessage(MapType.map.get(mapCode) + "["+keywords+"]：失败");
    }
}
